﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MyBet.Web.DAL;
using System.Web.Security;
using System.Web.Profile;
using System.ComponentModel.DataAnnotations;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using MyBet.Web.Services;

namespace MyBet.Web
{
    [DataContractAttribute(IsReference = true)]
    [Serializable()]
    public class BetObject
    {
        private int _matchId;
        private int _teamHomeScore;
        private int _teamAwayScore;

        [Key()]
        [DataMemberAttribute()]
        public int MatchId
        {
            get { return _matchId; }
            set { _matchId = value; }
        }

        [DataMemberAttribute()]
        public int TeamHomeScore
        {
            get { return _teamHomeScore; }
            set { _teamHomeScore = value; }
        }

        [DataMemberAttribute()]
        public int TeamAwayScore
        {
            get { return _teamAwayScore; }
            set { _teamAwayScore = value; }
        }

        /// <summary>
        /// Create object from database information
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public static BetObject CopyFrom(UserBets bet)
        {
            BetObject betTgt = new BetObject();
            betTgt.MatchId = bet.MatchId;
            betTgt.TeamHomeScore = bet.ScoreHome;
            betTgt.TeamAwayScore = bet.ScoreAway; 
            return betTgt;
        }

        /// <summary>
        /// Get prediction of user for a given event
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="userId"></param>
        /// <param name="championshipId"></param>
        /// <param name="dayNumber"></param>
        /// <param name="seasonId"></param>
        /// <returns></returns>
        public static IList<UserBets> GetBetsInDatabase(MyBetDBEntities dbContext, Guid userId, int eventId)
        {

            var queryBets = (from bets in dbContext.UserBets
                             where (bets.Matchs.EventId == eventId) && (bets.UserId == userId)
                             select bets);

            IList<UserBets> betList = queryBets.ToList();
            return betList;
        }

        /// <summary>
        /// Get prediction of user for a given event
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="userId"></param>
        /// <param name="championshipId"></param>
        /// <param name="dayNumber"></param>
        /// <param name="seasonId"></param>
        /// <returns></returns>
        public static Dictionary<int, UserBets> GetBetsInDatabase(Guid userId, int eventId)
        {
            Dictionary<int, UserBets> returnList = new Dictionary<int, UserBets>() ;
            IList<UserBets> betList = null;
            using (MyBetDBEntities dbContext = new MyBetDBEntities())
            {
                var queryBets = (from bets in dbContext.UserBets
                                 where (bets.Matchs.EventId == eventId) && (bets.UserId == userId)
                                 select bets);

                betList = queryBets.ToList();
            }
            foreach (UserBets item in betList)
            {
                returnList.Add(item.MatchId, item);
            }
            return returnList;
        }

        public static int GetBetScore(MyBetDBEntities dbContext, string userName, int eventId)
        {
            var query = (from scores in dbContext.EventScores
                         where (scores.EventId == eventId) && (scores.aspnet_Users.UserName == userName)
                         select scores.Score);
            int returnScore=-1;
            IList<int> scoreList = query.ToList();

            if (scoreList.Count > 0)
            {
                returnScore = scoreList[0];
            }
            return returnScore;
        }


        public static IList<UserBets> GetAllBetsInDatabase(MyBetDBEntities dbContext, int championshipId, int dayNumber, int seasonId)
        {

            var queryBets = (from bets in dbContext.UserBets
                             where (bets.Matchs.Events.Contests.ChampionshipId == championshipId) && (bets.Matchs.Events.DayNumber == dayNumber) && (bets.Matchs.Events.Contests.SeasonId == seasonId)
                             orderby bets.aspnet_Users.UserName
                             select bets);

            IList<UserBets> betList = queryBets.ToList();
            return betList;
        }

        public static void UpdateBetPoint(MyBetDBEntities dbContext, UserBets currentBet)
        {
            var queryBets = (from bets in dbContext.UserBets
                             where (bets.UserId == currentBet.UserId) && (bets.MatchId == currentBet.MatchId)
                             select bets);
            IList<UserBets> existingBets = queryBets.ToList();
            existingBets[0].Point = currentBet.Point;
        }

        public static PredictionService.PredictionValidationStatus SetPrediction(Guid userId,
                                          int eventId,
                                          List<int> matchId,
                                          List<int> scoreHome,
                                          List<int> scoreAway)
        {
            using (MyBetDBEntities dbContext = new MyBetDBEntities())
            {
                try
                {
                    Events currentEvent = EventObject.GetEventFromDatabase(dbContext, eventId);
                    if (currentEvent.CloseDate < DateTime.UtcNow)
                    {
                        return PredictionService.PredictionValidationStatus.DateExpired;
                    }

                    IList<UserBets> betList = BetObject.GetBetsInDatabase(dbContext, userId, eventId);
                    int i = 0;
                    foreach (int id in matchId)
                    {
                        var queryBetList = (from bet in betList
                                            where bet.MatchId == id
                                            select bet);
                        IList<UserBets> bets = queryBetList.ToList();
                        if (bets.Count == 0)
                        {
                            UserBets bet = new UserBets();
                            bet.UserId = userId;
                            bet.MatchId = id;
                            bet.ScoreHome = scoreHome[i];
                            bet.ScoreAway = scoreAway[i];
                            dbContext.UserBets.AddObject(bet);
                        }
                        else
                        {
                            if ((bets[0].ScoreHome != scoreHome[i])
                                || (bets[0].ScoreAway != scoreAway[i]))
                            {
                                bets[0].ScoreHome = scoreHome[i];
                                bets[0].ScoreAway = scoreAway[i];
                                dbContext.SaveChanges();
                            }
                        }
                        i++;
                    }
                    dbContext.SaveChanges();
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.Message);
                    return PredictionService.PredictionValidationStatus.GeneralFailure;
                }
                return PredictionService.PredictionValidationStatus.Success;
            }
        }

    }
}